home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_unix / j109lxa4.tar / ttydriv.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  12KB  |  514 lines

  1. /* TTY input line editing
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  * split screen by G. J. van der Grinten, PA0GRI
  4.  * command recall, and status line by Johan. K. Reinalda, WG7J
  5.  */
  6. #include <stdio.h>
  7. #ifdef __TURBOC__
  8. #include <conio.h>
  9. #endif
  10. #include <ctype.h>
  11. #include "global.h"
  12. #include "config.h"
  13. #include "mbuf.h"
  14. #include "session.h"
  15. #include "tty.h"
  16. #include "socket.h"
  17.  
  18. extern FILE *Rawterm;
  19.  
  20. #define    OFF    0
  21. #define    ON    1
  22.  
  23. #define    LINESIZE    256
  24.  
  25. #define CTLR    18      /* reprint current line */
  26. #define CTLU    21      /* delete current line in total */
  27. #define    CTLW    23        /* erase last word including preceding space */
  28. #define    CTLZ    26        /* EOF char in dos */
  29. #define    CTLB    02        /* use as F3 in dos but no editing */
  30. #define DEL    0x7f
  31.  
  32. extern int Numrows,Numcols;
  33.  
  34. #ifdef ALLSERV
  35.  
  36. static int  Lastsize = 1;
  37. static char Lastline[LINESIZE+1] = "\n";
  38.  
  39. /* Accept characters from the incoming tty buffer and process them
  40.  * (if in cooked mode) or just pass them directly (if in raw mode).
  41.  *
  42.  * Echoing (if enabled) is direct to the raw terminal. This requires
  43.  * recording (if enabled) of locally typed info to be done by the session
  44.  * itself so that edited output instead of raw input is recorded.
  45.  * Control-W added by g1emm again.... for word delete.
  46.  * Control-B/Function key 3 added by g1emm for line repeat.
  47.  */
  48.  
  49. struct mbuf *
  50. ttydriv(sp,c)
  51. struct session *sp;
  52. int c;
  53. {
  54.     struct mbuf *bp;
  55.     char *cp,*rp;
  56.     int cnt;
  57.  
  58.     switch(sp->ttystate.edit){
  59.     case OFF:
  60.         bp = ambufw(1);
  61.         *bp->data = c;
  62.         bp->cnt = 1;
  63.         if(sp->ttystate.echo){
  64.             if(sp->split){
  65.                 sp->tsavex = wherex();
  66.                 sp->tsavey = wherey();
  67.                 window(1,Numrows-1,Numcols,Numrows);
  68.                 gotoxy(sp->bsavex,sp->bsavey);
  69.                 highvideo();
  70.                 putch(c);
  71.                 normvideo();
  72.                 cputs("_\b");
  73.                 sp->bsavex = wherex();
  74.                 sp->bsavey = wherey();
  75.                 window(1,1,Numcols,Numrows-2);
  76.                 gotoxy(sp->tsavex,sp->tsavey);
  77.             } else {
  78. #ifdef UNIX
  79.                 putch(c);
  80. #else
  81.                 putc(c,Rawterm);
  82. #endif
  83.             }
  84.         }
  85.         return bp;
  86.     case ON:
  87.         if(sp->ttystate.line == NULLBUF)
  88.             sp->ttystate.line = ambufw(LINESIZE);
  89.  
  90.         bp = sp->ttystate.line;
  91.         cp = bp->data + bp->cnt;
  92.         /* Perform cooked-mode line editing */
  93. #ifdef notdef
  94.         switch(c & 0x7f){
  95. #endif
  96.         /* Allow for international character sets - WG7J */
  97.         switch(c){
  98.         case '\r':  /* CR and LF both terminate the line */
  99.         case '\n':
  100.             if(sp->ttystate.crnl)
  101.                 *cp = '\n';
  102.             else
  103.                 *cp = c;
  104.             if(sp->ttystate.echo){
  105.                 if(sp->split){
  106.                     highvideo();
  107.                     rp = bp->data;
  108.                     while(rp < cp) {
  109.                         putch(*rp++);
  110.                     }
  111.                     normvideo();
  112.                     clreol();
  113.                     cputs(Eol);
  114.                     clreol();
  115.                     sp->tsavex = wherex();
  116.                     sp->tsavey = wherey();
  117.                     window(1,Numrows-1,Numcols,Numrows);
  118.                     clrscr();
  119.                     cputs("_\b");
  120.                     sp->bsavex = wherex();
  121.                     sp->bsavey = wherey();
  122.                     window(1,1,Numcols,Numrows-2);
  123.                     gotoxy(sp->tsavex,sp->tsavey);
  124.                 } else {
  125. #ifdef UNIX
  126.                     cputs(Eol);
  127. #else
  128.                     fputs(Eol,Rawterm);
  129. #endif
  130.                 }
  131.             }
  132.             bp->cnt += 1;
  133.             sp->ttystate.line = NULLBUF;
  134.             Lastsize = bp->cnt;
  135.             memcpy(Lastline, bp->data, (size_t)Lastsize);
  136.             return bp;
  137.         case DEL:
  138.         case '\b':    /* Character delete */
  139.             if(bp->cnt != 0){
  140.                 bp->cnt--;
  141.                 if(sp->ttystate.echo){
  142.                     if(sp->split){
  143.                         sp->tsavex = wherex();
  144.                         sp->tsavey = wherey();
  145.                         window(1,Numrows-1,Numcols,Numrows);
  146.                         gotoxy(sp->bsavex,sp->bsavey);
  147.                         cputs(" \b\b_\b");
  148.                         sp->bsavex = wherex();
  149.                         sp->bsavey = wherey();
  150.                         window(1,1,Numcols,Numrows-2);
  151.                         gotoxy(sp->tsavex,sp->tsavey);
  152.                     } else {
  153. #ifdef UNIX
  154.                         cputs("\b \b");
  155. #else
  156.                         fputs("\b \b",Rawterm);
  157. #endif
  158.                     }
  159.                 }
  160.             }
  161.             break;
  162.         case CTLR:    /* print line buffer */
  163.             if(sp->ttystate.echo){
  164.                 if(sp->split) {
  165.                     sp->tsavex = wherex();
  166.                     sp->tsavey = wherey();
  167.                     window(1,Numrows-1,Numcols,Numrows);
  168.                     gotoxy(sp->bsavex,sp->bsavey);
  169.                     clrscr();
  170.                     rp = bp->data;
  171.                     while (rp < cp)
  172.                         putch(*rp++) ;
  173.                     cputs("_\b");
  174.                     sp->bsavex = wherex();
  175.                     sp->bsavey = wherey();
  176.                     window(1,1,Numcols,Numrows-2);
  177.                     gotoxy(sp->tsavex,sp->tsavey);
  178.                 } else {
  179. #ifdef UNIX
  180.                     cputs("^R");
  181.                     cputs(Eol);
  182.                     rp = bp->data;
  183.                     while (rp < cp)
  184.                         putch(*rp++);
  185. #else
  186.                     fprintf(Rawterm,"^R%s",Eol) ;
  187.                     rp = bp->data;
  188.                     while (rp < cp)
  189.                         putc(*rp++,Rawterm) ;
  190. #endif
  191.                 }
  192.             }
  193.             break ;
  194.         case CTLU:    /* Line kill */
  195.             if(sp->split) {
  196.                 sp->tsavex = wherex();
  197.                 sp->tsavey = wherey();
  198.                 window(1,Numrows-1,Numcols,Numrows);
  199.                 gotoxy(sp->bsavex,sp->bsavey);
  200.                 cputs(" \b");
  201.                 while(bp->cnt != 0){
  202.                     cputs("\b \b");
  203.                     bp->cnt--;
  204.                 }
  205.                 cputs("_\b");
  206.                 sp->bsavex = wherex();
  207.                 sp->bsavey = wherey();
  208.                 window(1,1,Numcols,Numrows-3);
  209.                 gotoxy(sp->tsavex,sp->tsavey);
  210.             } else {
  211.                 while(bp->cnt != 0){
  212.                     bp->cnt--;
  213.                     if(sp->ttystate.echo)
  214. #ifdef UNIX
  215.                         cputs("\b \b");
  216. #else
  217.                         fputs("\b \b",Rawterm);
  218. #endif
  219.                 }
  220.             }
  221.             break;
  222.         case CTLB:    /* Use last line to finish current */
  223.             cnt = bp->cnt;        /* save count so far */
  224.  
  225.             while(bp->cnt != 0){
  226.                 bp->cnt--;
  227.                 if(sp->ttystate.echo)
  228. #ifdef UNIX
  229.                     cputs("\b \b");
  230. #else
  231.                     fputs("\b \b", Rawterm);
  232. #endif
  233.             }
  234.             bp->cnt = cnt;
  235.  
  236.                         if(bp->cnt < (Lastsize-1)){
  237.                                 memcpy(bp->data+bp->cnt, &Lastline[bp->cnt], (size_t)(Lastsize-1) - bp->cnt);
  238.                                 bp->cnt = Lastsize-1;
  239.             }
  240.  
  241.             *(bp->data + bp->cnt) = '\0';    /* make it a string */
  242.             if(sp->ttystate.echo)
  243. #ifdef UNIX
  244.                 cputs(bp->data);
  245. #else
  246.                 fputs(bp->data, Rawterm);    /* repaint line */
  247. #endif
  248.             break ;
  249.         case CTLW:    /* erase word */
  250.             cnt = 0 ;    /* we haven't seen a printable char yet */
  251.             while(bp->cnt != 0){
  252.                 *(bp->data + bp->cnt--) = '\n';
  253.                 if(sp->ttystate.echo)
  254. #ifdef UNIX
  255.                     cputs("\b \b");
  256. #else
  257.                     fputs("\b \b", Rawterm);
  258. #endif
  259.                 if (isspace((int)*(bp->data + bp->cnt))) {
  260.                     if (cnt)
  261.                         break ;
  262.                 } else {
  263.                     cnt = 1 ;
  264.                 }
  265.             }
  266.             break ;
  267.         case UPARROW:  /* Recall previous command - WG7J */
  268.             if(Histry) {
  269.                 /* Blank out what's already there */
  270.                 while(bp->cnt != 0 && sp->ttystate.echo){
  271.                     bp->cnt--;
  272.                     cputs("\b \b");
  273.                 }
  274.                 /* Recall last command */
  275.                 strcpy(bp->data,Histry->cmd);
  276.                 bp->cnt = strlen(Histry->cmd);
  277.                 /* Adjust history */
  278.                 Histry = Histry->prev;
  279.                 /* repaint line */
  280.                 if(sp->ttystate.echo)
  281.                     cputs(bp->data);
  282.             }
  283.             break ;
  284.         case DNARROW:  /* Recall next command - WG7J */
  285.             if(Histry) {
  286.                 /* Blank out what's already there */
  287.                 while(bp->cnt != 0 && sp->ttystate.echo){
  288.                     bp->cnt--;
  289.                     cputs("\b \b");
  290.                 }
  291.                 /* Adjust history */
  292.                 Histry = Histry->next;
  293.                 /* Recall last command */
  294.                 strcpy(bp->data,Histry->cmd);
  295.                 bp->cnt = strlen(Histry->cmd);
  296.                 /* repaint line */
  297.                 if(sp->ttystate.echo)
  298.                     cputs(bp->data);
  299.             }
  300.             break ;
  301.         default:    /* Ordinary character */
  302.             *cp = c;
  303.             bp->cnt++;
  304.  
  305.             /* ^Z apparently hangs the terminal emulators under
  306.              * DoubleDos and Desqview. I REALLY HATE having to patch
  307.              * around other people's bugs like this!!!
  308.              */
  309.             if(sp->ttystate.echo &&
  310. #ifndef    AMIGA
  311.              c != CTLZ &&
  312. #endif
  313.              bp->cnt < LINESIZE-1){
  314.                 if(sp->split) {
  315.                     sp->tsavex = wherex();
  316.                     sp->tsavey = wherey();
  317.                     window(1,Numrows-1,Numcols,Numrows);
  318.                     gotoxy(sp->bsavex,sp->bsavey);
  319.                     putch(c);
  320.                     cputs("_\b");
  321.                     sp->bsavex = wherex();
  322.                     sp->bsavey = wherey();
  323.                     window(1,1,Numcols,Numrows-2);
  324.                     gotoxy(sp->tsavex,sp->tsavey);
  325.                 } else {
  326. #ifdef UNIX
  327.                     putch(c);
  328. #else
  329.                     putc(c,Rawterm);
  330. #endif
  331.                 }
  332.  
  333.             } else if(bp->cnt >= LINESIZE-1){
  334. #ifdef UNIX
  335.                 write(1, "\007", 1);
  336. #else
  337.                 putc('\007',Rawterm);    /* Beep */
  338. #endif
  339.                 bp->cnt--;
  340.             }
  341.             break;
  342.         }
  343.         break;
  344.     }
  345.     return NULLBUF;
  346. }
  347.  
  348. #else
  349.  
  350.  
  351. /* Accept characters from the incoming tty buffer and process them
  352.  * (if in cooked mode) or just pass them directly (if in raw mode).
  353.  *
  354.  * Echoing (if enabled) is direct to the raw terminal. This requires
  355.  * recording (if enabled) of locally typed info to be done by the session
  356.  * itself so that edited output instead of raw input is recorded.
  357.  */
  358. struct mbuf *
  359. ttydriv(sp,c)
  360. struct session *sp;
  361. int c;
  362. {
  363.     struct mbuf *bp;
  364.     char *cp,*rp;
  365.  
  366.     switch(sp->ttystate.edit){
  367.     case OFF:
  368.         bp = ambufw(1);
  369.         *bp->data = c;
  370.         bp->cnt = 1;
  371.         if(sp->ttystate.echo)
  372. #ifdef UNIX
  373.             putch(c);
  374. #else
  375.             putc(c,Rawterm);
  376. #endif
  377.  
  378.         return bp;
  379.     case ON:
  380.         if(sp->ttystate.line == NULLBUF)
  381.             sp->ttystate.line = ambufw(LINESIZE);
  382.  
  383.         bp = sp->ttystate.line;
  384.         cp = bp->data + bp->cnt;
  385.         /* Allow for international character sets - WG7J */
  386.         /* Perform cooked-mode line editing */
  387. /*        switch(c & 0x7f){ */
  388.         switch(c) {
  389.         case '\r':    /* CR and LF both terminate the line */
  390.         case '\n':
  391.             if(sp->ttystate.crnl)
  392.                 *cp = '\n';
  393.             else
  394.                 *cp = c;
  395.             if(sp->ttystate.echo)
  396. #ifdef UNIX
  397.                 cputs(Eol);
  398. #else
  399.                 fputs(Eol,Rawterm);
  400. #endif
  401.  
  402.             bp->cnt += 1;
  403.             sp->ttystate.line = NULLBUF;
  404.             return bp;
  405.         case DEL:
  406.         case '\b':    /* Character delete */
  407.             if(bp->cnt != 0){
  408.                 bp->cnt--;
  409.                 if(sp->ttystate.echo)
  410. #ifdef UNIX
  411.                     cputs("\b \b");
  412. #else
  413.                     fputs("\b \b",Rawterm);
  414. #endif
  415.             }
  416.             break;
  417.         case CTLR:    /* print line buffer */
  418.             if(sp->ttystate.echo){
  419. #ifdef UNIX
  420.                 cputs("^R");
  421.                 cputs(Eol);
  422.                 rp = bp->data;
  423.                 while (rp < cp)
  424.                     putch(*rp++);
  425. #else
  426.                 fprintf(Rawterm,"^R%s",Eol) ;
  427.                 rp = bp->data;
  428.                 while (rp < cp)
  429.                     putc(*rp++,Rawterm) ;
  430. #endif
  431.             }
  432.             break ;
  433.         case CTLU:    /* Line kill */
  434.             while(bp->cnt != 0){
  435.                 bp->cnt--;
  436.                 if(sp->ttystate.echo){
  437. #ifdef UNIX
  438.                     cputs("\b \b");
  439. #else
  440.                     fputs("\b \b",Rawterm);
  441. #endif
  442.                 }
  443.             }
  444.             break;
  445.         case UPARROW:  /* Recall previous command - WG7J */
  446.             if(Histry) {
  447.                 /* Blank out what's already there */
  448.                 while(bp->cnt != 0 && sp->ttystate.echo){
  449.                     bp->cnt--;
  450.                     cputs("\b \b");
  451.                 }
  452.                 /* Recall last command */
  453.                 strcpy(bp->data,Histry->cmd);
  454.                 bp->cnt = strlen(Histry->cmd);
  455.                 /* Adjust history */
  456.                 Histry = Histry->prev;
  457.                 /* repaint line */
  458.                 if(sp->ttystate.echo)
  459.                     cputs(bp->data);
  460.             }
  461.             break ;
  462.         case DNARROW:  /* Recall next command - WG7J */
  463.             if(Histry) {
  464.                 /* Blank out what's already there */
  465.                 while(bp->cnt != 0 && sp->ttystate.echo){
  466.                     bp->cnt--;
  467.                     cputs("\b \b");
  468.                 }
  469.                 /* Adjust history */
  470.                 Histry = Histry->next;
  471.                 /* Recall last command */
  472.                 strcpy(bp->data,Histry->cmd);
  473.                 bp->cnt = strlen(Histry->cmd);
  474.                 /* repaint line */
  475.                 if(sp->ttystate.echo)
  476.                     cputs(bp->data);
  477.             }
  478.             break ;
  479.         default:    /* Ordinary character */
  480.             *cp = c;
  481.             bp->cnt++;
  482.  
  483.             /* ^Z apparently hangs the terminal emulators under
  484.              * DoubleDos and Desqview. I REALLY HATE having to patch
  485.              * around other people's bugs like this!!!
  486.              */
  487.             if(sp->ttystate.echo &&
  488. #ifndef    AMIGA
  489.              c != CTLZ &&
  490. #endif
  491.              bp->cnt < LINESIZE-1){
  492. #ifdef UNIX
  493.                 putch(c);
  494. #else
  495.                 putc(c,Rawterm);
  496. #endif
  497.  
  498.             } else if(bp->cnt >= LINESIZE-1){
  499. #ifdef UNIX
  500.                 write(1, "\007", 1);
  501. #else
  502.                 putc('\007',Rawterm);    /* Beep */
  503. #endif
  504.                 bp->cnt--;
  505.             }
  506.             break;
  507.         }
  508.         break;
  509.     }
  510.     return NULLBUF;
  511. }
  512.  
  513. #endif /*ALLSERV*/
  514.